home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / dev / misc / LEDA_src.lha / LEDA-3.1c-source / src / dict / _ch_hash1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-17  |  5.0 KB  |  280 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _ch_hash1.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/impl/ch_hash1.h>
  16.  
  17. //------------------------------------------------------------------------------
  18. //
  19. //  hashing with chaining and table doubling
  20. //
  21. //  S. Naeher (1994)
  22. //
  23. //------------------------------------------------------------------------------
  24.  
  25.  
  26. ch_hash1_elem ch_hash1::STOP;
  27.  
  28. #define NIL  GenPtr(this)
  29.  
  30. int ch_hash1::next_pow(int x) const
  31. { // return next power of 2
  32.   int result = 1;    
  33.   while ((x>>=1) > 0) result <<= 1;
  34.   return result;
  35.  }
  36.  
  37.  
  38. ch_hash1_item ch_hash1::lookup(GenPtr x) const
  39. { register ch_hash1_item q = table;
  40.  
  41.   STOP.k = x;
  42.  
  43.   if (int_type())
  44.   { q += (int(x) & table_size_1);  // table_size = power of 2
  45.     while (q->k != x) q = q->succ;
  46.    }
  47.   else
  48.   { q += (hash_fct(x) & table_size_1);
  49.     while (cmp(q->k,x)) q = q->succ;
  50.    }
  51.  
  52.   return (q == &STOP) ? 0 : q;
  53. }
  54.  
  55.  
  56. void ch_hash1::change_inf(ch_hash1_item p, GenPtr x)
  57. { clear_inf(p->i);
  58.   p->i = x;
  59.   copy_inf(p->i);
  60.  }
  61.  
  62. void ch_hash1::del(GenPtr x)
  63.   ch_hash1_item p = table + (int(x) & table_size_1);
  64.  
  65.   if (p->k == x)
  66.   { clear_key(p->k);
  67.     clear_inf(p->i);
  68.     p->k = NIL;
  69.     count--;
  70.     if (count == low_table) rehash(low_table);
  71.     return;
  72.   }
  73.  
  74.   STOP.k = x;
  75.  
  76.   if (int_type())
  77.      while (p->succ->k != x) p = p->succ;
  78.   else
  79.      while (cmp(p->succ->k,x)) p = p->succ;
  80.  
  81.   ch_hash1_item q = p->succ;
  82.  
  83.   if (q==&STOP) return;
  84.  
  85.   clear_key(q->k);
  86.   clear_inf(q->i);
  87.  
  88.   p->succ = q->succ;
  89.   delete q;
  90.   count--;
  91.   if (count == low_table) rehash(low_table);
  92.  }
  93.  
  94.  
  95. void ch_hash1::del_item(ch_hash1_item q)
  96. { register ch_hash1_item p = table + (hash_fct(q->k) & table_size_1);
  97.   clear_key(q->k);
  98.   clear_inf(q->i);
  99.   if (p==q) 
  100.      p->k = NIL;
  101.   else
  102.     { while(p->succ != q) p = p->succ;
  103.       p->succ = q->succ;
  104.       delete q;
  105.      }
  106.   count--;
  107.   if (count == low_table) rehash(low_table);
  108.  }
  109.   
  110.   
  111.   
  112.  
  113. ch_hash1_item ch_hash1::insert(GenPtr x, GenPtr y)
  114.   ch_hash1_item p = table + (int(x) & table_size_1);
  115.   ch_hash1_item q = p;
  116.  
  117.   STOP.k = x;
  118.  
  119.   if (int_type())
  120.      while (p->k != x) p = p->succ;
  121.   else
  122.      while (cmp(p->k,x)) p = p->succ;
  123.  
  124.   if (p != &STOP)
  125.   { clear_inf(p->i);
  126.     p->i = y;
  127.     copy_inf(p->i);
  128.     return p;
  129.    }
  130.  
  131.   count++;
  132.   copy_key(x);
  133.   copy_inf(y);
  134.  
  135.   if (q->k == NIL) 
  136.     { q->k = x;
  137.       q->i = y;
  138.      }
  139.   else
  140.     { q->succ = new ch_hash1_elem(x,y,q->succ);
  141.       q = q->succ;
  142.      }
  143.  
  144.   if (count == high_table) rehash(high_table);
  145.  
  146.   return q;
  147. }
  148.  
  149.  
  150.  
  151. void ch_hash1::destroy()
  152.   for(int i=0; i < table_size; i++) 
  153.   { ch_hash1_item p = table[i].succ;
  154.     ch_hash1_item q = p;
  155.     while (p != &STOP)
  156.     { clear_key(p->k);
  157.       clear_inf(p->i);
  158.       q = p;
  159.       p = p->succ;
  160.       delete q;
  161.     }
  162.    }
  163.   //delete[] table;
  164.   free(table);
  165. }
  166.  
  167.  
  168. void ch_hash1::init(int T)
  169.   register ch_hash1_item p;
  170.   register ch_hash1_item stop;
  171.  
  172.   table_size = T;
  173.   table_size_1 = T-1;
  174.  
  175.   low_table  = (T > 1024) ? T/2 : -1;
  176.   high_table = 2*T;
  177.  
  178.   //table = new ch_hash1_elem[table_size];
  179.   table = (ch_hash1_elem*)malloc(table_size*sizeof(ch_hash1_elem));
  180.  
  181.   stop = table + table_size;
  182.   for(p=table; p<stop; p++) 
  183.   { p->succ = &STOP;
  184.     p->k = NIL;
  185.   }
  186.  
  187.   count = 0;
  188. }
  189.  
  190.  
  191. void ch_hash1::rehash(int T)
  192.  
  193.   register ch_hash1_item p;
  194.   register ch_hash1_item q;
  195.   register ch_hash1_item r;
  196.   int i;
  197.  
  198.   ch_hash1_item old_table = table;
  199.   int old_table_size = table_size;
  200.   int old_count = count;
  201.  
  202.   init(T);
  203.  
  204.   if (int_type())
  205.      for (i=0; i<old_table_size; i++)
  206.      { p = old_table[i].succ;
  207.        while(p != &STOP)
  208.        { r = p->succ;
  209.          q = table + (int(p->k) & table_size_1);
  210.          p->succ = q->succ;
  211.          q->succ = p;
  212.          p = r;
  213.         }
  214.       }
  215.   else
  216.      for (i=0; i<old_table_size; i++)
  217.      { p = old_table[i].succ;
  218.        while(p != &STOP)
  219.        { r = p->succ;
  220.          q = table + (hash_fct(p->k) & table_size_1);
  221.          p->succ = q->succ;
  222.          q->succ = p;
  223.          p = r;
  224.         }
  225.       }
  226.  
  227.   ch_hash1_item stop = old_table+old_table_size;
  228.   for (p=old_table; p<stop; p++)
  229.     if (p->k != NIL) 
  230.     {  q = table + (int(p->k) & table_size_1);
  231.        if (q->k == NIL)
  232.         { q->k = p->k;
  233.           q->i = p->i;
  234.          }
  235.        else
  236.          q->succ = new ch_hash1_elem(p->k,p->i,q->succ);
  237.     }
  238.    
  239.   count = old_count;
  240.  
  241.   //delete[] old_table;
  242.   free(old_table);
  243. }
  244.  
  245.  
  246. ch_hash1::ch_hash1(const ch_hash1& D)
  247. { ch_hash1_item p;
  248.   init(D.table_size);
  249.   for (int i=0; i<table_size; i++)
  250.   { p = D.table[i].succ;
  251.     while(p != &(D.STOP))
  252.     { insert(p->k,p->i);
  253.       D.copy_key(p->k);
  254.       D.copy_inf(p->i);
  255.       p = p->succ;
  256.     }
  257.   }
  258. }
  259.  
  260.  
  261. ch_hash1& ch_hash1::operator=(const ch_hash1& D)
  262. { ch_hash1_item p;
  263.   clear();
  264.   for (int i=0; i<D.table_size; i++)
  265.   { p = D.table[i].succ;
  266.     while(p != &(D.STOP))
  267.     { insert(p->k,p->i);
  268.       p = p->succ;
  269.      }
  270.    }
  271.   return *this;
  272. }
  273.  
  274.